package com.vayne.demo;

import com.vayne.annotation.Super;
import com.vayne.bean.Course;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Map;

/**
 * 依赖查找：
 * 1）实时查找
 * 2）延时查找
 * 3）类型查找：单个
 * 4）类型查找：集合
 *
 * <p>FactoryBean、BeanFactory、ObjectFactory</p>
 *
 * @author xuerui.zhang
 * @since 2020/1/6 下午4:38
 */
public class DependencyLookupDemo {

    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("dependency_lookup_config.xml");
        // findRealByName(beanFactory);
        // findLazyByName(context);
        // findSingleByType(beanFactory);
        // findMapByType(beanFactory);
        findByAnnotation(beanFactory);
    }

    private static void findByAnnotation(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map<String, Object> courseMap = listableBeanFactory.getBeansWithAnnotation(Super.class);
            System.out.println("Load By Annotation：" + courseMap);
        }
    }

    private static void findMapByType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map<String, Course> courseMap = listableBeanFactory.getBeansOfType(Course.class);
            System.out.println("查询列表：" + courseMap);
        }
    }

    private static void findSingleByType(BeanFactory beanFactory) {
        Course bean = beanFactory.getBean(Course.class);
        System.out.println("Real Search（直接查找）by type：" + bean.toString());
    }

    private static void findRealByName(BeanFactory beanFactory) {
        Course course = (Course) beanFactory.getBean("course");
        System.out.println("Real Search（直接查找）by name：" + course.toString());
    }

    private static void findLazyByName(BeanFactory beanFactory) {
        // mark: getBean(Course.class) 没有生成新的 bean 怎么理解？
        // ObjectFactory 懒加载的原因导致的
        // noinspection unchecked
        ObjectFactory<Course> objectFactory = (ObjectFactory<Course>) beanFactory.getBean("objectFactoryBean");
        Course course = objectFactory.getObject();
        course.setId(2L);
        System.out.println("Lazy Search（间接查找）：" + course.toString());
    }
}
